﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.IO.IsolatedStorage;

namespace KopyKat
{
    public partial class MainPage : UserControl
    {
        public System.Windows.Threading.DispatcherTimer _timer;
        public string KopyKatLastClipboard;
        public string KopyKatCurrClipboard;
        public string KopyKatLastListen;
        public string KopyKatCurrListen;
        public int KopyKatClipBChangedLast;
        public int KopyKatCloudChangedLast;
        private IsolatedStorageSettings kkuserprefs = IsolatedStorageSettings.ApplicationSettings;
        private IsolatedStorageSettings kkuserclipb = IsolatedStorageSettings.ApplicationSettings;

        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            #region Running State/Installer Checks
            KopyKatShowUserPrefs(KopyKatUserPrefUpdate(false));
            // check to make sure we're running OOB
            if (!App.Current.IsRunningOutOfBrowser)
            { // We are NOT running OOB so ask them to start the app on desktop
                // check to make sure the app is installed
                // if not, only show the installer
                if (App.Current.InstallState == InstallState.Installed)
                {
                    KKInstallButtonLine1.Text = HtmlPage.Document.GetElementById("kopykatuemail").GetAttribute("Value");
                    KKInstallButtonLine2.Text = "Has KopyKat NOW!";
                    KopyKatInstallButton.Visibility = Visibility.Visible;
                }
                else
                {   //We are NOT Installed so we should be in the webpage.
                    // KopyKatInstallButton.Content = "I want THE MY KopyKat";
                    //May be good to test for the expected PAGE values and react...
                    KKInstallButtonLine1.Text = HtmlPage.Document.GetElementById("kopykatuemail").GetAttribute("Value");
                    KKInstallButtonLine2.Text = "wants KopyKat NOW!";
                    KopyKatShowUserPrefs(KopyKatUserPrefUpdate(true));
                    KopyKatInstallButton.Visibility = Visibility.Visible;
                }
            }
            else
            { // We are running OOB so check for updates 
                KopyKatInstallButton.Visibility = Visibility.Collapsed;
                KopyKatTextBlockMsg.Text = "Checking for KopyKat updates... ";
                App.Current.CheckAndDownloadUpdateCompleted += new CheckAndDownloadUpdateCompletedEventHandler(Current_CheckAndDownloadUpdateCompleted);
                App.Current.CheckAndDownloadUpdateAsync();
            }
            #endregion
        }
        public string KopyKatUserPrefUpdate(bool kkuserprefwebupdatemode)
        {
            if (!kkuserclipb.Contains("kkcbpnt"))
            {
                kkuserclipb.Add("kkcbpnt", "0");
                kkuserclipb.Add("kksppnt", "0");
                kkuserclipb.Add("kklspnt", "0");
            }
            if (!kkuserprefs.Contains("kopykatuemail"))
            {
                kkuserprefs.Add("kopykatuemail", "default@notmeworld.com");
                kkuserprefs.Add("kopykatuid", "defaultuser");
                kkuserprefs.Add("kopykatserver", "http://kopykat.horseoff.com/");
                kkuserprefs.Add("kopykatspeak", "http://kopykat.horseoff.com/server/pastehere.php");
                kkuserprefs.Add("kopykatlisten", "http://kopykat.horseoff.com/server/copyhere.php?KopyKatlistenname=");
            }
            if (kkuserprefwebupdatemode)
            { //if we think we've got something in the DOM that looks like 
                kkuserprefs["kopykatuemail"] = HtmlPage.Document.GetElementById("kopykatuemail").GetAttribute("Value");
                kkuserprefs["kopykatuid"] = HtmlPage.Document.GetElementById("kopykatuid").GetAttribute("Value");
                kkuserprefs["kopykatserver"] = HtmlPage.Document.GetElementById("kopykatserver").GetAttribute("Value");
                kkuserprefs["kopykatspeak"] = HtmlPage.Document.GetElementById("kopykatspeak").GetAttribute("Value");
                kkuserprefs["kopykatlisten"] = HtmlPage.Document.GetElementById("kopykatlisten").GetAttribute("Value");
                return "kkisowebpage";
            } else return "kkisodefault";
        }
        public void KopyKatShowUserPrefs(string kkmessage)
        {
            KopyKatTextBlockMsg.Text += kkmessage;
            if (KopyKatInstallButton.Visibility.Equals(Visibility.Visible))
            { //Scroll down if the button is blocking
                KopyKatTextBlockMsg.Text += kkmessage;
                KopyKatTextBlockMsg.Text += kkmessage;
                KopyKatTextBlockMsg.Text += kkmessage;
            }
            KopyKatTextBlockMsg.Text += "\n kopykatuemail: " + kkuserprefs["kopykatuemail"].ToString();
            KopyKatTextBlockMsg.Text += "\n kopykatuid: " + kkuserprefs["kopykatuid"].ToString();
            KopyKatTextBlockMsg.Text += "\n kopykatserver: " + kkuserprefs["kopykatserver"].ToString();
            KopyKatTextBlockMsg.Text += "\n kopykatspeak: " + kkuserprefs["kopykatspeak"].ToString();
            KopyKatTextBlockMsg.Text += "\n kopykatlisten: " + kkuserprefs["kopykatlisten"].ToString();
        }
        //-KopyKat Stuff to do after the update check is done.
        private void Current_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
        { // We have just gotten back from server and we are up to date, so now we start running the local OOB stuff
            KopyKatTextBlockMsg.Text += " ... is now DONE";
            //-KopyKat Start the ping timer
            KopyKatClipBChangedLast = 0;
            KopyKatCloudChangedLast = 0;
            _timer = new System.Windows.Threading.DispatcherTimer();
            _timer.Interval = new TimeSpan(0, 0, 1);
            _timer.Tick += new EventHandler(KopyKatTimerCheckChanges);
            _timer.Start();
        }
        //-KopyKat Stuff to do on the Timer Ticks
        private void KopyKatTimerCheckChanges(object sender, EventArgs e)
        {
            string debugnote = DateTime.Now.ToString("h:mm:ss.fff") + " Clipboard has: \n ";
            KopyKatClipBChangedLast++;
            KopyKatCloudChangedLast++;
            if ((bool)Debug.IsChecked)
            {
                KopyKatTextBlockMsg.Visibility = Visibility.Visible;
                KopyKatTextBlockMsg.Text = debugnote;
                if (!kkuserprefs.Contains("kopykatuemail"))
                {
                    KopyKatTextBlockMsg.Text += "THIS SUCKS... Read ERROR in isoStore!";
                }
                else
                {
                    KopyKatShowUserPrefs(debugnote);
                }
            }
            else
            {
                KopyKatTextBlockMsg.Visibility = Visibility.Collapsed;
            }
            try { KopyKatCurrClipboard = Clipboard.GetText(); }
            catch (System.Security.SecurityException ex)
            {
                string msg = "Wow.. your system is not letting KopyKat get to the Clipboard: " + ex.Message;
                MessageBox.Show(msg);
            }
            //Logic to Push clipboard changes to the server
            if (KopyKatLastClipboard != KopyKatCurrClipboard)
            {   // ok the clipboard is different from when we checked last.  Snapshot it and set some timers.
                string kpnt = kkuserclipb["kkcbpnt"].ToString();
                kkuserclipb["kkcbpnt"] = (int.Parse(kpnt) + 1).ToString();
                kkuserclipb.Add(kpnt, KopyKatCurrClipboard); //Add the clipboard data to the local history
                KopyKatTextBlockMsg.Text = debugnote + KopyKatCurrClipboard;
                KopyKatLastClipboard = KopyKatCurrClipboard;  //Got an new clipboard, so reset the change detector
                KopyKatCurrListen = KopyKatCurrClipboard;     //Sync the listen to what I'm about to say.
                KopyKatClipBChangedLast = 0; //Reset our timer
                //Go update the cloud but make sure it has been quite a few sec
                if ((bool)Connect.IsChecked && (KopyKatCloudChangedLast > 2)) KopyKatKlippush(sender);
                if ((bool)Debug.IsChecked) KopyKatTextBlockMsg.Text += "\n DEBUG: Should be update Clould here.";
            }
            if (true) //The go listen request logic conditions right now we listen
            {   //Logic to go check on server changes. Do it always but I'll keep the check
                if ((bool)Connect.IsChecked)
                {   //Check the server file
                    WebClient KopyKatWebGet = new WebClient();
                    KopyKatWebGet.DownloadStringCompleted += new DownloadStringCompletedEventHandler(KopyKatWebGet_DownloadStringCompleted);
                    //KopyKatWebGet.DownloadStringAsync(new Uri("http://kopykat.notmeworld.com/server/copyhere.php?KopyKatlistenname=" + "TestDefaultFileName" + ".txt"));
                    KopyKatWebGet.DownloadStringAsync(new Uri(kkuserprefs["kopykatlisten"].ToString() + kkuserprefs["kopykatuid"].ToString() + ".txt"));
                    if ((bool)Debug.IsChecked) KopyKatTextBlockMsg.Text = "Sending: " + kkuserprefs["kopykatlisten"].ToString() + kkuserprefs["kopykatuid"].ToString() + ".txt";
                }
            }
            if ((bool)History.IsChecked)
            { //Display History
                KopyKatTextBlockMsg.Text = debugnote + "History\n";
                int i = 0;
                while (i < int.Parse(kkuserclipb["kkcbpnt"].ToString()))
                {
                    KopyKatTextBlockMsg.Text += kkuserclipb[i.ToString()] + "\n";
                    i++;
                }
            }
         }

        private void KopyKatWebGet_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if ((KopyKatCurrListen != e.Result) && (KopyKatClipBChangedLast > 3))
                { //Someing changed and We have not changed for a few clicks... so lets update
                    KopyKatCurrClipboard = e.Result; //So we do not fire off a clipboard change
                    KopyKatLastClipboard = e.Result;
                    Clipboard.SetText(e.Result); //Set the clipboard
                    KopyKatTextBlockMsg.Text = DateTime.Now.ToString("h:mm:ss.fff") + " Server posted new clipboard: \n" + e.Result + "/n";
                    KopyKatLastListen = KopyKatCurrListen; //Do not really need this right now... thinging of a FILO for the cliboards.
                    KopyKatCurrListen = e.Result;
                }
                if ((KopyKatCurrListen != e.Result) && (KopyKatClipBChangedLast < 3))
                { //The cloud clipboard didn't update lets push it again
                    if ((bool)Connect.IsChecked && (KopyKatCloudChangedLast > 2)) KopyKatKlippush(sender);
                }
            }
            else { KopyKatTextBlockMsg.Text = DateTime.Now.ToString("h:mm:ss.fff") + "Listen ERROR: " + "\n" + e.Error.ToString(); }
        }

        private void KopyKatKlippush(object sender)
        {
            if ((bool)Debug.IsChecked) KopyKatTextBlockMsg.Text += "\n DEBUG: In KopyKatKlippush.";
            DateTime myBoundaryTime = new DateTime();
            WebClient KopyKatWebpush = new WebClient();
            //Setup stuff for the multipart boundary
            string fileCATXML = KopyKatCurrClipboard;
            string CRLF = "\r\n";
            string boundary = "KopyKat-------------------KopyKat" + myBoundaryTime.Ticks.ToString();
            string contentType = "multipart/form-data; boundary=" + boundary;
            KopyKatWebpush.Headers["Content-Type"] = contentType;
            string contentDump = "";
            //The -- are important and nasty... need the -- at the end to end atleast using the apache php bitnami setup I was using
            //contentDump += "--" + boundary + CRLF + "Content-Disposition: form-data; name=\"SomeCrap\"" + CRLF + CRLF + "crapvalue1" + CRLF;
            //contentDump += "--" + boundary + CRLF + "Content-Disposition: form-data; name=\"thefilename\"; filename=\"" + "TestDefaultFileName" + ".txt\"" + CRLF + "Content-Type: text/plain" + CRLF + CRLF + fileCATXML + CRLF;
            //contentDump += "--" + boundary + CRLF + "Content-Disposition: form-data; name=\"hiddenname1\"" + CRLF + CRLF + "hiddenValue1" + CRLF;
            contentDump += "--" + boundary + CRLF + "Content-Disposition: form-data; name=\"thefilename\"; filename=\"" + kkuserprefs["kopykatuid"].ToString() + ".txt\"" + CRLF + "Content-Type: text/plain" + CRLF + CRLF + fileCATXML + CRLF;
            contentDump += "--" + boundary + "--" + CRLF; //-- for THE END        
            KopyKatWebpush.UploadStringCompleted += new UploadStringCompletedEventHandler(KopyKatWebpushUploadCompleted);
            //KopyKatWebpush.UploadStringAsync(new Uri("http://kopykat.notmeworld.com/server/pastehere.php"), "Post", contentDump);
            if ((bool)Debug.IsChecked)
            {
                KopyKatTextBlockMsg.Text += "\n DEBUG: In KopyKatKlippush about to push message.";
                KopyKatTextBlockMsg.Text += "\n DEBUG: URI: " + kkuserprefs["kopykatspeak"].ToString();
            }
            KopyKatWebpush.UploadStringAsync(new Uri(kkuserprefs["kopykatspeak"].ToString()), "Post", contentDump);
            return;
        }
        private void KopyKatWebpushUploadCompleted(object sender, UploadStringCompletedEventArgs e)
        {
            if (e.Error == null) 
            {
                if ((bool)Debug.IsChecked) KopyKatTextBlockMsg.Text += "\nCopyCAT server says: \n============\n" + e.Result + "\n";
            }
            else { KopyKatTextBlockMsg.Text += "\n ERROR: \n" + e.Error.ToString() + "\n"; }
        }

        private void KopyKatInstallButton_Click(object sender, RoutedEventArgs e)
        {
            // App.Current.Install();
            if (!App.Current.IsRunningOutOfBrowser)
            {
                if (App.Current.InstallState == InstallState.Installed)
                {
                    KopyKatTextBlockMsg.Text = "Attempting to run the Out of Browser CopyCat Application";
                    // System.Windows.Browser.HtmlPage.Window.Invoke("EmulateApp");
                    // App.Current.Install();
                }
                else
                {
                    KopyKatTextBlockMsg.Text = "Attempting to Install Out of Browser CopyCat Application";
                    // System.Windows.Browser.HtmlPage.Window.Invoke("InstallApp");
                    App.Current.Install();
                    // System.Windows.Browser.HtmlPage.Window.Navigate(System.Windows.Browser.HtmlPage.Document.DocumentUri);
                }
                App.Current.CheckAndDownloadUpdateAsync();
            }
        }
    }
}
